home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue46 / Alfresco / AAVarLst.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-04-24  |  6.2 KB  |  223 lines

  1. {*********************************************************}
  2. {* AAVarLst                                              *}
  3. {* Copyright (c) Julian M Bucknall 1998-1999             *}
  4. {* All rights reserved.                                  *}
  5. {*********************************************************}
  6. {* List of variables/values                              *}
  7. {*********************************************************}
  8.  
  9. {Note: this unit is released as freeware. In other words, you are free
  10.        to use this unit in your own applications, however I retain all
  11.        copyright to the code. JMB}
  12.  
  13. unit AAVarLst;
  14.  
  15. interface
  16.  
  17. uses
  18.   AAStStk,
  19.   SysUtils;
  20.  
  21. type
  22.   PaaVariableNode = ^TaaVariableNode;
  23.   TaaVariableNode = packed record
  24.     vnString : PaaString255;
  25.     vnValue  : double;
  26.   end;
  27.  
  28. const
  29.   aaMaxVarItems = MaxInt div sizeof(TaaVariableNode);
  30.  
  31. type
  32.   PaaVariableArray = ^TaaVariableArray;
  33.   TaaVariableArray = array [0..pred(aaMaxVarItems)] of TaaVariableNode;
  34.  
  35. type
  36.   TaaVariableList = class
  37.     private
  38.       FArray    : PaaVariableArray;
  39.       FCapacity : integer;
  40.       FCount    : integer;
  41.       FStStack  : TaaStringStack;
  42.     protected
  43.       function vlGetName(aInx : integer) : TaaString255;
  44.       function vlGetValue(const aName : TaaString255) : double;
  45.       procedure vlSetValue(const aName  : TaaString255;
  46.                            const aValue : double);
  47.       procedure vlSetCapacity(aValue : integer);
  48.  
  49.       function vlFindName(const aName  : TaaString255;
  50.                             var aIndex : integer) : boolean;
  51.       procedure vlGrowArray;
  52.     public
  53.       constructor Create;
  54.         {-create the variable list}
  55.       destructor Destroy; override;
  56.         {-destroy the variable list; releasing all memory}
  57.  
  58.       procedure Clear;
  59.         {-remove all variables from list}
  60.       function GetValue(const aName  : TaaString255;
  61.                           var aValue : double) : boolean;
  62.         {-return true and the value of a variable if the variable
  63.           exists; false otherwise}
  64.       function IsEmpty : boolean;
  65.         {-is the list empty?}
  66.  
  67.       property Capacity : integer
  68.          read FCapacity write vlSetCapacity;
  69.         {-capacity of the list}
  70.       property Count : integer
  71.          read FCount;
  72.         {-count of variables in the list}
  73.       property Name[aInx : integer] : TaaString255
  74.          read vlGetName;
  75.         {-array of variable names}
  76.       property Value[const aName : TaaString255] : double
  77.          read vlGetValue write vlSetValue;
  78.         {-associative array of variable names and their values; on
  79.           read, if the variable does not exist, 0.0 is returned}
  80.     end;
  81.  
  82. implementation
  83.  
  84.  
  85. {===TaaVariableList===================================================}
  86. constructor TaaVariableList.Create;
  87. begin
  88.   inherited Create;
  89.   FStStack := TaaStringStack.Create(1024);
  90. end;
  91. {--------}
  92. destructor TaaVariableList.Destroy;
  93. begin
  94.   FStStack.Free;
  95.   Capacity := 0;
  96.   inherited Destroy;
  97. end;
  98. {--------}
  99. procedure TaaVariableList.Clear;
  100. begin
  101.   FCount := 0;
  102.   FStStack.Clear;
  103. end;
  104. {--------}
  105. function TaaVariableList.GetValue(const aName  : TaaString255;
  106.                                     var aValue : double) : boolean;
  107. var
  108.   Inx : longint;
  109. begin
  110.   Result := vlFindName(aName, Inx);
  111.   if Result then
  112.     aValue := FArray^[Inx].vnValue;
  113. end;
  114. {--------}
  115. function TaaVariableList.IsEmpty : boolean;
  116. begin
  117.   Result := (FCount = 0);
  118. end;
  119. {--------}
  120. function TaaVariableList.vlFindName(const aName  : TaaString255;
  121.                                       var aIndex : integer) : boolean;
  122. var
  123.   L, R, M : longint;
  124.   MidNode : PaaVariableNode;
  125. begin
  126.   {binary search}
  127.   L := 0;
  128.   R := pred(Count);
  129.   while (L <= R) do begin
  130.     M := (L + R) div 2;
  131.     MidNode := @FArray^[M];
  132.     if (MidNode^.vnString^ < aName) then
  133.       L := succ(M)
  134.     else if (MidNode^.vnString^ > aName) then
  135.       R := pred(M)
  136.     else {found it} begin
  137.       aIndex := M;
  138.       Result := true;
  139.       Exit;
  140.     end;
  141.   end;
  142.   aIndex := L;
  143.   Result := false;
  144. end;
  145. {--------}
  146. function TaaVariableList.vlGetName(aInx : integer) : TaaString255;
  147. begin
  148.   if (0 <= aInx) and (aInx < Count) then
  149.     Result := FArray^[aInx].vnString^;
  150. end;
  151. {--------}
  152. function TaaVariableList.vlGetValue(const aName : TaaString255) : double;
  153. begin
  154.   if not GetValue(aName, Result) then
  155.     Result := 0.0;
  156. end;
  157. {--------}
  158. procedure TaaVariableList.vlGrowArray;
  159. begin
  160.   if (Capacity = 0) then
  161.     Capacity := 4
  162.   else if (Capacity < 64) then
  163.     Capacity := Capacity * 2
  164.   else
  165.     Capacity := Capacity + (Capacity div 4);
  166. end;
  167. {--------}
  168. procedure TaaVariableList.vlSetValue(const aName  : TaaString255;
  169.                                      const aValue : double);
  170. var
  171.   Inx : integer;
  172. begin
  173.   {make sure there's enough room}
  174.   if (Count = Capacity) then
  175.     vlGrowArray;
  176.   {first the simple case}
  177.   if (Count = 0) then begin
  178.     FArray^[0].vnString := FStStack.Push(aName);
  179.     FArray^[0].vnValue := aValue;
  180.     inc(FCount);
  181.   end
  182.   {next the case where the name is already present}
  183.   else if vlFindName(aName, Inx) then begin
  184.     FArray^[Inx].vnValue := aValue;
  185.   end
  186.   {finally the case where the name is not present}
  187.   else begin
  188.     if (Inx <> Count) then
  189.       Move(FArray^[Inx], FArray^[Inx+1],
  190.            (Count - Inx) * sizeof(TaaVariableNode));
  191.     FArray^[Inx].vnString := FStStack.Push(aName);
  192.     FArray^[Inx].vnValue := aValue;
  193.     inc(FCount);
  194.   end;
  195. end;
  196. {--------}
  197. procedure TaaVariableList.vlSetCapacity(aValue : integer);
  198. var
  199.   NewArray  : PaaVariableArray;
  200.   CopyCount : longint;
  201. begin
  202.   if (aValue <> FCapacity) then begin
  203.     if (aValue < FCapacity) then begin
  204.       CopyCount := aValue;
  205.       if (aValue < FCount) then
  206.         FCount := aValue;
  207.     end
  208.     else
  209.       CopyCount := FCapacity;
  210.     if (aValue > 0) then
  211.       GetMem(NewArray, longint(aValue) * sizeof(TaaVariableNode));
  212.     if (CopyCount > 0) then
  213.       Move(FArray^, NewArray^, CopyCount * sizeof(TaaVariableNode));
  214.     if (FCapacity > 0) then
  215.       FreeMem(FArray, longint(FCapacity) * sizeof(TaaVariableNode));
  216.     FArray := NewArray;
  217.     FCapacity := aValue;
  218.   end;
  219. end;
  220. {====================================================================}
  221.  
  222. end.
  223.